#include "core_pch.h"
#include "BaseObj.h"
#include "RTTI.h"



static s32_t __totalMemObj = 0;
MObj::MObj()
{
	++__totalMemObj;
}

MObj::~MObj()
{
	--__totalMemObj;
}


void* MObj::operator new(size_t stSizeInBytes)
{
	if (stSizeInBytes == 0)
		stSizeInBytes = 1;

	void* p =  coreAlloc( stSizeInBytes);

	if (p == 0)
		throw std::bad_alloc();

	return p;
}

void* MObj::operator new[](size_t stSizeInBytes)
{
	if ( stSizeInBytes == 0)
		stSizeInBytes = 1;

	void* p =  coreAlloc (stSizeInBytes);

	if (p == 0)
		throw std::bad_alloc();

	return p;
}

//---------------------------------------------------------------------------
void MObj::operator delete(void* pvMem, size_t stElementSize)
{
    if (pvMem)
    {
		coreFree( pvMem);
    }
}
//---------------------------------------------------------------------------
void MObj::operator delete[](void* pvMem, size_t stElementSize)
{
    if (pvMem)
    {
		coreFree( pvMem);
    } 
}



///////////////////////////////////////////////////////////
RObj::~RObj() 
{
}

void RObj::IncRef ()
{
	coreAtomicInc( mReferenceCount);
}

void RObj::DecRef ()
{
	coreAtomicDec( mReferenceCount);
	if (mReferenceCount == 0)
	{
		delete this;
	}
}

///////////////////////////////////////////////////////////
ClassDef* Obj::RTTI()
{
	static ClassDef _rtti_("Obj", 0, 0);
	return &_rtti_;
}



Obj::Obj()
{
}

Obj::~Obj()
{
}

bool Obj::IsTypeOf( ClassDef* testType)
{
	return GetClass()->IsTypeOf( testType);
}

bool Obj::GetMemberData( const char* name, PropData& data)
{
	PropDef* desc = GetClass()->GetProp( name);
	return GetMemberData( desc, data);
}

bool Obj::GetMemberData( PropDef* desc, PropData& data)
{
	_check( desc);

	data.Def = desc;
	data.Data = ((unsigned char* )this) + desc->Pos;

	return true;
}

Obj* Obj::Clone()
{
	Obj* retObj = GetClass()->New();
	CopyMemDataTo( retObj, GetClass());
	return retObj;
}

void Obj::CopyMemDataTo( Obj* retObj, ClassDef* _type)
{
	assert( GetClass()->IsTypeOf( _type));
	assert( retObj->GetClass()->IsTypeOf( _type));

	// object super class list
	TArray< ClassDef* > clsList;
	_type->GetInheritClassList( clsList);

	TArray< ClassDef* >::Iterator inherIt( clsList);

	while( inherIt)
	{
		ClassDef* loadType = *inherIt;
		inherIt.Next();

		TArray< PropDef*>::Iterator dataIt = loadType->PropIt();
		while( dataIt)
		{
			PropDef* dataDef = *dataIt;
			dataIt.Next();
			
			PropData thisVal;
			GetMemberData( dataDef, thisVal);

			PropData dstVal;
			retObj->GetMemberData( dataDef, dstVal);

			thisVal.CopyTo( dstVal);


		}


	}

	retObj->PostLoad();
}

	
void Obj::PostLoad()
{
	// object super class list
	TArray< ClassDef* > clsList;
	GetClass()->GetInheritClassList( clsList);

	TArray< ClassDef* >::Iterator inherIt( clsList);

	while( inherIt)
	{
		ClassDef* loadType = *inherIt;
		inherIt.Next();

		TArray< PropDef*>::Iterator dataIt = loadType->PropIt();
		while( dataIt)
		{

			PropDef* dataDef = *dataIt;
			dataIt.Next();

			PropData dataVal;
			GetMemberData( dataDef, dataVal);

			if( dataDef->Type == Data_RefObj_Ptr)// all data objs
			{
				s32_t size = dataVal.Num();
				for( s32_t i = 0; i < size; ++i)
				{
					P(Obj)* dataObj = (P(Obj)*)dataVal[i];
					if( *dataObj)
					{
						(*dataObj)->PostLoad();
					}
				}
			}
			
		}

	}
}
	
void Obj::OnDataModified( PropDef* def)
{
	DataListener* lis = GetDataListener();
	if( lis)
	{
		lis->NotifyDataModified(this, def);
	}
}

Obj::DataListener* Obj::GetDataListener()
{
	return 0;
}

void Obj::OnStream( Pack* pack)
{
}

